#include "decodificador.h"

Decodificador::Decodificador(Memoria &memoria) : memoria_(memoria)
{
}

void Decodificador::decodificar(int posicion)
{
	// El "gran" switch.
	switch (memoria_[posicion]) {
		case 0x00:
			instruccion_.setTipo(NOP);
			break;
		case 0x01:
			instruccion_.setTipo(LXI);
			instruccion_.setRegistro(REGISTRO_B);
			instruccion_.setValorInmediato16(getInmed16(posicion + 1));
			break;
		case 0x02:
			instruccion_.setTipo(STAX);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x03:
			instruccion_.setTipo(INX);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x04:
			instruccion_.setTipo(INR);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x05:
			instruccion_.setTipo(DCR);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x06:
			instruccion_.setTipo(MVI);
			instruccion_.setRegistro(REGISTRO_B);
			instruccion_.setValorInmediato8(getInmed8(posicion + 1));
			break;
		case 0x07:
			instruccion_.setTipo(RLC);
			break;
		case 0x08:
			// Instruccion invalida.
			break;
		case 0x09:
			instruccion_.setTipo(DAD);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x0A:
			instruccion_.setTipo(LDAX);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x0B:
			instruccion_.setTipo(DCX);
			instruccion_.setRegistro(REGISTRO_B);
			break;
		case 0x0C:
			instruccion_.setTipo(INR);
			instruccion_.setRegistro(REGISTRO_C);
			break;
		case 0x0D:
			instruccion_.setTipo(DCR);
			instruccion_.setRegistro(REGISTRO_C);
			break;
		case 0x0E:
			instruccion_.setTipo(MVI);
			instruccion_.setRegistro(REGISTRO_C);
			instruccion_.setValorInmediato8(getInmed8(posicion + 1));
			break;
		case 0x0F:
			instruccion_.setTipo(RRC);
			break;
		default:
			// TODO: Decidir como manejar esto
			break;
	}
}

Instruccion Decodificador::getInstruccion()
{
	return instruccion_;
}

byte Decodificador::getInmed8(int posicion)
{
	return memoria_[posicion];
}

word Decodificador::getInmed16(int posicion)
{
	return memoria_[posicion] + (memoria_[posicion+1] << 8);
}
